import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:interview/components/app/app_prompt_overlay.dart';
import 'package:interview/controller/navigation_controller.dart';
import 'package:interview/controller/user_controller.dart';
import 'dart:async';
import 'package:interview/utils/logger.dart';
import 'package:get/get.dart' hide Response;

class Http {
  static late Dio _dio;
  static final userController = Get.find<UserController>();
  static final navigation = Get.find<NavigationController>();
  // 基础URL，超时等
  static const String _baseUrl = 'https://api-harmony-teach.itheima.net/hm/'; // 默认baseUrl
  static const Duration _connectTimeout =  Duration(milliseconds: 10000);  // 连接超时
  static const Duration _receiveTimeout = Duration(milliseconds: 10000);  // 响应超时

  // 初始化 Dio
  static void init({String baseUrl = _baseUrl}) {
    _dio = Dio(BaseOptions(
      baseUrl: baseUrl,
      connectTimeout: _connectTimeout,
      receiveTimeout: _receiveTimeout,
       validateStatus: (status) {
        // 处理 401 错误，让它通过响应拦截器来统一处理
        return status != null && status < 500;
      },
    ));

    // 添加请求拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler ) {
        Logger.info("网络请求 URL: ${options.uri}, 方法: ${options.method}", tag: "HTTP 请求");
        // 不需要携带 Token 的 URL 列表
        const noTokenUrls = [
          "https://api-harmony-teach.itheima.net/hm/question/type", // 添加需要排除的接口 URL
        ];
        final token = userController.getToken();
        // 有token时 携带token  首页接口不做token校验
        if(token.isNotEmpty && !noTokenUrls.contains(options.uri.toString())){
          options.headers['Authorization'] = 'Bearer $token';
        }
        return handler.next(options); // 必须调用 handler.next() 继续请求
      },
       onResponse: (response, handler) {
        Logger.info("响应数据: ${response.data}", tag: "HTTP 响应");
        return handler.next(response); // 确保继续响应处理
      },
      onError: (DioException e, handler) {
        String errorMessage = "网络请求错误";
        if (e.response != null) {
          errorMessage += "，状态码: ${e.response?.statusCode}，URL: ${e.requestOptions.uri}";
          errorMessage += "，错误响应: ${e.response?.data}";
        } else {
          errorMessage += "，错误信息: ${e.message}";
        }
        Logger.error(errorMessage, tag: "HTTP 报错");
        return handler.next(e); // 继续错误处理
      },
    ));
  }

  /// 处理响应
  static T _handleResponse<T>(Response response, BuildContext? context) {
    if (response.statusCode != null && response.statusCode! >= 200 && response.statusCode! < 300) {
      // 如果是泛型 Map<String, dynamic> 或 List，则直接返回数据
      if (T == Map || T == List || T == dynamic) {
        return response.data;
      }
      // 其他情况尝试手动解析
      return response.data as T;
    } else {

    // 处理 401 状态码，跳转到登录页面
    if (response.statusCode == 401) {
        // 清除失效的token
        userController.clearUser();
        // 如果 context 不为空，显示 AppPromptOverlay 和跳转到登录页面
        if (context != null) {
          AppPromptOverlay.show(context: context, message: "登录已过期");
          navigation.push('/login');
        }
        // 可以抛出异常，或者直接返回一个特定的错误
        throw DioException(
          requestOptions: response.requestOptions,
          response: response,
          error: "未授权，请重新登录。",
        );
      }
      throw DioException(
        requestOptions: response.requestOptions,
        response: response,
        error: "请求失败，状态码: ${response.statusCode}",
      );
    }
  }


  // 通用 GET 请求
  static Future<T> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Options? options, 
    BuildContext? context, // 可选参数 context
    // required Null Function(dynamic received, dynamic total) onProgress,
  }) async {
    try {
      final response = await _dio.get(path, queryParameters: queryParameters, options: options);
      return _handleResponse<T>(response,context);
    } catch (e) {
      rethrow;
    }
  }

  // 通用 POST 请求
  static Future<T> post<T>(
    String path, {
    required dynamic data, // 确保 data 参数是必填项
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
    BuildContext? context, // 可选参数 context
  }) async {
    try {
      final response = await _dio.post<T>(
        path,
        data: data,
        options: options,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );
      return _handleResponse<T>(response,context);
    } catch (e) {
      rethrow; // 错误可以在调用时捕获
    }
  }


  /// 支持进度回调的 GET 请求 当响应头没有 Content-Length 无法触发
  static Future<T> getWithProgress<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Function(int received, int total)? onProgress, // 进度回调
  }) async {
    try {
      final response = await _dio.get<T>(
        path,
        queryParameters: queryParameters,
        options: Options( responseType: ResponseType.stream),
        onReceiveProgress: (received, total) {
          Logger.info("onReceiveProgress 回调触发: received=$received, total=$total", tag: 'HTTP GET');
          if (total > 0) {
            onProgress?.call(received, total);
          } else {
            Logger.warn("总大小未知 (Content-Length 缺失)", tag: 'HTTP GET');
          }
        },
      );
      return response.data!;
    } catch (e) {
      Logger.error("GET 请求失败: $e", tag: 'HTTP GET');
      rethrow;
    }
  }
}

